﻿using System.Linq.Expressions;
using NPOI.SS.Formula.Functions;
using NPOI.Util;
using Simple.Services.System;
using Simple.Services.System.Recipes.Models;


namespace Simple.Services;

public class FoodMaterialsService : BusinessBaseService
{
    private readonly SimpleDbContext _context;

    public FoodMaterialsService(SimpleDbContext context, ISimpleService services) : base(services)
    {
        _context = context;
    }

    public async Task<List<FoodMaterialsModel>> GetAsync(FoodMaterialsPageInputModel input)
    {
        var query =  _context.Set<FoodMaterials>().AsQueryable();

        // 根据条件查询
        if (input.FoodMaterialsTypeId.HasValue)
        {
            query = query.Where(p => p.FoodMaterialsTypeId == input.FoodMaterialsTypeId);
        }
        if (!string.IsNullOrEmpty(input.FoodName))
        {
            query = query.Where(p => EF.Functions.Like(p.FoodName, $"%{input.FoodName}%"));
        }

        var positions = await query.ToListAsync();
        return MapperHelper.Map<List<FoodMaterialsModel>>(positions);
    }

    public async Task<PageResultModel<FoodMaterialsModel>> GetPageAsync(FoodMaterialsPageInputModel input)
    {
        var result = new PageResultModel<FoodMaterialsModel>();
        var query =_context.Set<FoodMaterials>().AsQueryable();

        // 根据条件查询
        if (input.FoodMaterialsTypeId.HasValue)
        {
            query = query.Where(p => p.FoodMaterialsTypeId == input.FoodMaterialsTypeId);
        }
        if (!string.IsNullOrEmpty(input.FoodName))
        {
            query = query.Where(p => EF.Functions.Like(p.FoodName, $"%{input.FoodName}%"));
        }


        ////1.创建表达式参数（指定参数或变量的类型:p）  
        //var param = Expression.Parameter(typeof(T), "t");
        ////2.构建表达式体(类型包含指定的属性:p.Name)  
        //var body = Expression.Property(param, string.IsNullOrEmpty(input.Sort) ? "CreatedTime" : input.Sort);
        ////3.根据参数和表达式体构造一个lambda表达式  
        //var order = Expression.Lambda<Func<T, FoodMaterials>>(Expression.Convert(body, typeof(FoodMaterials)), param);

        // 获取总数量
        result.TotalRows = await query.CountAsync();

        // 分页查询
        query = query.OrderBy(x => input.Sort).Page(input.PageNo, input.PageSize);
        var positions = await query.ToListAsync();
        result.Rows = MapperHelper.Map<List<FoodMaterialsModel>>(positions);

        result.SetPage(input);
        result.CountTotalPage();

        return result;

    }

    public async Task<int> AddAsync(FoodMaterialsModel model)
    {
        if (await _context.Set<FoodMaterials>().AnyAsync(p => p.Id != model.Id && p.FoodName == model.FoodName && p.FoodMaterialsTypeId == model.FoodMaterialsTypeId))
        {
            throw AppResultException.Status409Conflict("存在相同名称的食材");
        }

        var position = MapperHelper.Map<FoodMaterials>(model);
        await _context.AddAsync(position);
        return await _context.SaveChangesAsync();
    }

    public async Task<int> UpdateAsync(FoodMaterialsModel model)
    {
        if (await _context.Set<FoodMaterials>().AnyAsync(p => p.Id != model.Id && p.FoodName == model.FoodName && p.FoodMaterialsTypeId == model.FoodMaterialsTypeId))
        {
            throw AppResultException.Status409Conflict("存在相同名称的食材");
        }

        var foodMaterials = await _context.Set<FoodMaterials>()
            .Where(p => model.Id == p.Id)
            .FirstOrDefaultAsync();
        if (foodMaterials == null)
        {
            throw AppResultException.Status404NotFound("找不到食材，更新失败");
        }
        MapperHelper.Map<FoodMaterialsModel, FoodMaterials>(model, foodMaterials);
        _context.Update(foodMaterials);
        int ret = await _context.SaveChangesAsync();
        if (ret == 0)
        {
            throw AppResultException.Status200OK("更新记录数为0");
        }

        return ret;
    }

    public async Task<int> DeleteAsync(IEnumerable<Guid> ids)
    {
        var positions = await _context.Set<FoodMaterials>()
            .Where(p => ids.Contains(p.Id))
            .ToListAsync();
        _context.RemoveRange(positions);
        return await _context.SaveChangesAsync();
    }

    public async Task<List<FoodMaterialsTypeModel>> GetTypeListAsync()
    {
        var query = _context.Set<FoodMaterialsType>().AsQueryable();
        var positions = await query.ToListAsync();
        return MapperHelper.Map<List<FoodMaterialsTypeModel>>(positions);
    }
}
